package utils

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"math/rand"
	"net"
	"regexp"
	"strings"
	"time"
)

func GetFreePort() (int, error) {
	addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
	if err != nil {
		return 0, err
	}

	l, err := net.ListenTCP("tcp", addr)
	if err != nil {
		return 0, err
	}
	defer l.Close()
	return l.Addr().(*net.TCPAddr).Port, nil
}

func GetEth0IPv4() (string, error) {
	// 获取所有网络接口
	interfaces, err := net.Interfaces()
	if err != nil {
		return "", err
	}

	// 遍历所有接口
	for _, iface := range interfaces {
		// 查找接口名为 eth0
		if iface.Name == "eth0" {
			// 获取该接口的所有地址
			addrs, err := iface.Addrs()
			if err != nil {
				return "", err
			}

			// 遍历所有地址，查找 IPv4 地址
			for _, addr := range addrs {
				// 地址类型是 IP 地址
				if ipNet, ok := addr.(*net.IPNet); ok && ipNet.IP.To4() != nil {
					return ipNet.IP.String(), nil
				}
			}
		}
	}
	return "", fmt.Errorf("no IPv4 address found for eth0")
}

// GetEncryptPassword 加密密码
func GetEncryptPassword(password string, salt string) string {
	// 对密码先 md5 加密
	hash := md5.New()
	hash.Write([]byte(password))
	md5Password := hex.EncodeToString(hash.Sum(nil))

	// 将 md5 密码与盐值拼接，再次 md5 加密
	hash.Reset()
	hash.Write([]byte(md5Password + salt))
	return hex.EncodeToString(hash.Sum(nil))
}

// GetRandomStr 生成随机字符串
func GetRandomStr(length int, special bool) string {
	// 定义基本字符集（字母和数字）
	chars := []string{
		"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
		"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
		"w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
		"H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
		"S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
		"3", "4", "5", "6", "7", "8", "9",
	}

	// 如果需要特殊字符，添加特殊字符到字符集
	if special {
		specialChars := []string{
			"!", "@", "#", "|", "/", ";", "%",
			"^", "(", ")", "-", "_", "<", ">", "~", "+", ",", ".",
		}
		chars = append(chars, specialChars...)
	}

	// 初始化随机种子
	rand.Seed(time.Now().UnixNano())

	// 打乱字符集
	rand.Shuffle(len(chars), func(i, j int) {
		chars[i], chars[j] = chars[j], chars[i]
	})

	// 生成随机字符串
	var sb strings.Builder
	for i := 0; i < length; i++ {
		sb.WriteString(chars[rand.Intn(len(chars))])
	}

	return sb.String()
}

// 函数，根据文件类型和 base64 数据生成路径和 MIME 类型
func ProcessBase64Data(file int, base64Data string) (string, string, error) {
	var path string
	var re *regexp.Regexp
	re = regexp.MustCompile(`^data:(\S+?)/(\S+?);base64,`)

	// 根据文件类型选择路径和正则表达式
	switch file {
	case 1:
		path = "avatar/"
	case 2:
		path = "cover/"
	case 3:
		path = "music/"
	case 4:
		path = "video/"
	case 5:
		path = "images/"
	case 6:
		path = "dynamic_image/"
	case 7:
		path = "audio/"
	case 8:
		path = "avatar/"
	default:
		return "", "", fmt.Errorf("invalid file type")
	}

	// 使用正则表达式提取 MIME 类型
	matches := re.FindStringSubmatch(base64Data)
	if len(matches) < 2 {
		return "", "", fmt.Errorf("invalid base64 data format")
	}

	mimeType := matches[2]
	// 将 MIME 类型转换为小写，确保后缀统一
	mimeType = strings.ToLower(mimeType)

	// 返回文件路径和 MIME 类型
	return path, mimeType, nil
}
